<?php
/**
 * Hy - 系统基础模块
 *
 * 系统基础模块用于提供前后台系统均会使用到的功能模块
 *
 * Copyright (c) 2013 YinHailin All rights reserved.
 * @Author: YinHailin
 * @Authorize: Boren Network
 * @Created by YinHailin at 2013-11-20
 */

defined('LY_VERSION') or exit();

class BasicMod extends SheetMod {

  /* 构造方法 */
  public function __construct() {
    //插件更新处理
    if (C('APP_DEBUG') || !is_dir(ROOT_PATH.'Runtime/Plugin/Cache/')) {
      plugin_register();
    }
  }

  /*
   * 进行系统登录操作
   * @param integer $type 操作类型 1=密码登录 2=Cookie登录 3=获取登录状态 其它=退出登录
   * @param array $user 用户信息
   + 应包含：用户唯一标识 - 如ID（key），用户token（token），用户sid（sid），用户当前活动时间（time），用户当前活动IP（ip）
   + 示例：array('key' => 1, 'token' => '7fef6171469e80d32c0559f88b377245', 'sid'=>'7fef6171469e80d32c0559f88b377245', 'time'=>'1378134118', ip=>'192.168.1.138')
   * @param array $config 必要配置信息
   + 应包含：Cookie、Session存储名（keyName），[可选]token超时时间 - 天（tokenTimeout），[可选]sid超时时间 - 秒（sidTimeout），[可选]是否单IP登录（thisIp），[可选]是否单浏览器登录（thisBrowser）
   + 示例：array('keyName' => 'hyAdmin', 'tokenTimeout' => 1, 'sidTimeout'=>1200, 'thisIp'=>true, thisBrowser=>true)
   * @return string 返回操作后登录状态
   */
  protected function SetLogin($type, $user, $config = array()) {
    //实例化登录类
    $objLogin = new HyLogin($config['keyName'], $config['tokenTimeout'], $config['sidTimeout'], $config['thisIp'], $config['thisBrowser']);
    $objLogin->SetLoginInfo($user['ip'], $user['sid'], $user['time']);
    switch ($type) {
      case 1 :
        //密码登录
        return $objLogin->SetPasswordLogin($user['key'], $user['token'], $user['sid']);
        break;
      case 2 :
        //Cookie登录
        return $objLogin->SetCookieLogin();
        break;
      case 3 :
        //获取登录状态
        return $objLogin->GetLoginStatus($user['token']);
        break;
      default :
        //退出登录
        return $objLogin->SetLogout();
    }
  }

  /*
   * 按照规则检查字段
   * @param string $field 要检查的字段
   * @param string $value 检查字段的值
   * @param string $rule 检查规则，支持正则表达式
   * @param string $prompt 检查不符合规则时的提示文字
   * @param string $extra 额外的参数，例如在检查唯一性时，传递数据表名称
   * @param string $extend 额外的搜索条件
   * @return string
   */
  protected function CheckField($field, $value, $rule, $prompt, $extra = '', $extend = '') {
    $result = true;
    switch ($rule) {
      case 'unique' :
        $obj = M($extra);
        $where = $field.'="'.$value.'"';
        if ($extend != '') $where .= ' AND '.$extend;
        $data = $obj->Where($where)->Find();
        $data = deep_htmlspecialchars_decode($data);
        if ($data != '') { $result = false;}
        break;
      case 'uniform' :
        if ($value != $extra) { $result = false;}
        break;
      default :
        $result = regex($value, $rule);
    }
    if (!$result) $this->Error($prompt);
  }

  /*
   * 获取分类及其子类的ID
   * + 将分类及其子类以ID,ID,ID的形式组织后返回
   * @param string $table 数据表
   * @param integer $id 父ID
   * @param beolean $isChild 是否是在进行子循环，若是子循环，返回值前会附有逗号
   * @return string
   */
  protected function GetIdList($table, $id, $isChild = false) {
    $obj = M($table);

    $id = intval($id);
    $data = $obj->Field('`id`')->Where('`parent_id`='.$id)->Select();
    $data = deep_htmlspecialchars_decode($data);
    foreach ($data as $value) {
      $string = $string .','. $value['id'];
      $string = $string . $this->GetIdList($table, $value['id'], true);
    }
    if ($isChild) {
      return $string;
    } else {
      return $id . $string;
    }
  }

  /*
   * 获取站点信息
   * @return array
   */
  protected function GetSiteInfo() {
    $objSite = M(self::$dataSite);
    $site = $objSite->Where('id = 1')->Find();
    $site = deep_htmlspecialchars_decode($site);
    return $site;
  }

  /*
   * 获取多级分类的分类列表
   * + 将分类列表以数组的形式读取出来
   * @param string $table 分类所在的数据表名（不需要添加数据表前缀）
   * @param integer $parent_id 该分类作为父类的ID
   * @param string $maxGrade 分类显示深度，-1表示不限制级数
   + 例如 $maxGrade 的值为2， 则会罗列出$parent_id级别下（包括该级）2级分类，3级及其以上的分类就不会显示
   * @param string $extend 扩展查询条件
   * @param string $order 排序方式
   * @param string $order 返回记录限制
   * @param string $grade 当前分类级数
   * @return array
   */
  protected function GetSortList($table, $parent_id=0, $maxGrade = -1, $extend='', $order = '`sequence` asc, `id` asc', $limit='', $grade = 1) {
    if ($maxGrade === -1 || $grade <= $maxGrade) {
      $obj = M($table);
      if ($extend === '') {
        $where = '`parent_id` = '.$parent_id;
      } else {
        $where =$extend . ' AND `parent_id`='.$parent_id;
      }
      $list = $obj->Where($where)->Order($order)->Limit($limit)->Select();
      $list = deep_htmlspecialchars_decode($list);
      foreach ($list as $key => $value) {
        $list[$key]['child_sort'] = $this->GetSortList($table, $value['id'], $maxGrade, $extend, $order, $limit, $grade+1);
      }
      return $list;
    }
  }

  /*
   * 组织分类列表
   * + 将分类列表以特定的形式进行排列为深度为2及以上的数组，便于模板输出
   * @param array $list 分类数据
   * @param string $grade 当前分类级数，默认为一级分类(1)
   * @return array
   */
  protected function SetSortList($list, $grade = 1) {
    $tab = '&nbsp;&nbsp;&nbsp;&nbsp;';
    $sign = '|--&nbsp;';
    for ($i = 1; $i < $grade; $i++) {
      $string .= $tab;
    }
    foreach ($list as $key => $value) {
      //组织数据
      $data[] = array(
        'id' => $value['id'],
        'sort_name' => $string . $sign . $value['sort_name'],
        'status' => $value['status'],
        'sequence' => $value['sequence'],
      );
      //获取子菜单
      if (trim($value['child_sort']) !== '') {
        $data = array_merge($data, (array)$this->SetSortList($value['child_sort'], $grade+1));
      }
    }
    return $data;
  }
}